package com.hqyj.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hqyj.dao.UserInfoMapper;
import com.hqyj.pojo.UserInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * 项目:exam-springboot-230701
 * 描述:
 * 时间:2023/10/10 9:18
 * 作者:admin
 * 版本:1.0
 **/
@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {

    @Autowired
    RedisTemplate<String,Object> redisTemplate;
    @Resource
    UserInfoMapper userInfoMapper;
    //缓存击穿
    @GetMapping("/test")
    public void test01() throws InterruptedException {
        //获取当前线程id
        Long id  = Thread.currentThread().getId();
        log.info("线程{}开始业务",id);
        //定义锁
        String key = "suo:power";
        String value = UUID.randomUUID()+"";
        boolean is  = redisTemplate.opsForValue().setIfAbsent(key,value,3,TimeUnit.MINUTES);
        //判断当前线程是否进入
        if(!is){
          log.info("线程{}等待上一个线程完成",id);
          while(!redisTemplate.opsForValue().setIfAbsent(key,value,3,TimeUnit.MINUTES)){
              //继续等待
              Thread.sleep(1000);
          }
        }

        try {
            List<String> list = null;
            //查询缓存是否有数据
            Object obj = redisTemplate.opsForValue().get("test");
            if(obj==null){
                log.info("缓存中没有数据，从数据库查询获取");
                //查询数据库
                list = userInfoMapper.queryRoleByUserName("pig");
                //把数据存入redis缓存中
                redisTemplate.opsForValue().set("test",list,2, TimeUnit.MINUTES);

            }else{
                log.info("缓存中有数据，从缓存中获取数据");
                //从缓存中去数据
                list = (List<String>)obj;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //删除建
            if(redisTemplate.opsForValue().get(key).equals(value)){
                    //删除缓存
                 redisTemplate.delete(key);
                 log.info("线程 {}业务处理完毕，释放锁",id);
            }
        }

    }

     //缓存穿透
     @GetMapping("/test01")
     public void test02(Integer id){
        Object obj = redisTemplate.opsForValue().get("test01");
        if(obj==null){
            log.info("缓存无数据,从数据库中取数据");
            QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id",id);
            //查询
            UserInfo userInfo = userInfoMapper.selectById(id);
            log.info("userInfo={}",userInfo);
            if(userInfo!=null){
                //存入缓存
                redisTemplate.opsForValue().set("test01",userInfo,5,TimeUnit.MINUTES);
            }else{
                //存入缓存,值为空字符串，失效时间小于 非空字符串存入缓存的时间
                redisTemplate.opsForValue().set("test01","",2,TimeUnit.MINUTES);
            }

        }else{
            log.info("从缓存中取数据");

        }
     }

}
